package com.pikachu.web.util;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;

/**
 * Json工具类
 * @author huang_kangjie
 * @create 2018-03-31 14:28
 **/
@Log4j2
public class JsonUtils {

     private static final ObjectMapper mapper = new ObjectMapper();

     /**
      * 转换成json字符串
      * @param obj
      * @return
      */
     public static String toJson(Object obj){
          if(obj == null){
               return null;
          }
          try {
               return mapper.writeValueAsString(obj);
          } catch (IOException e) {
               log.error(String.format("obj=[%s]", obj.toString()), e);
          }
          return null;
     }

     /**
      *  将json转化为对象
      * @param json
      * @param clazz
      * @param <T>
      * @return
      */
     public static <T> T fromJson(String json,Class<T> clazz){
          if(json == null){
               return null;
          }
          try {
               return mapper.readValue(json, clazz);
          } catch (IOException e) {
               log.error(String.format("json=[%s]", json), e);
          }
          return null;
     }

     /**
      * map 转 Object
      * @param map
      * @param clazz
      * @param <T>
      * @return
      */
     public static <T> T mapToObject(Map<String,Object> map, Class<T> clazz){
          if(map == null){
               return null;
          }
          try {
               return mapper.readValue(toJson(map), clazz);
          } catch (IOException e) {
               log.error(String.format("map=[%s]", map), e);
          }
          return null;
     }

     /**
      * 将json对象转化为集合类型
      * @param json json对象
      * @param collectionClazz 具体的集合类的class，如：ArrayList.class
      * @param clazz 集合内存放的对象的class
      * @return
      */
     public static <T> Collection<T> fromJson(String json, Class<? extends Collection> collectionClazz, Class<T> clazz){
          if(json == null){
               return null;
          }
          try {
               return mapper.readValue(json, getCollectionType(collectionClazz,clazz));
          } catch (IOException e) {
               log.error(String.format("json=[%s]", json), e);
          }
          return null;
     }

     /**
      * 获取JavaType
      * @param collectionClass     集合的class
      * @param elementClasses      元素的class
      * @return
      */
     private static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
          return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
     }
}
